# 创建套接字
import socket
import sys
import threading
import os
import traceback
import json
# 传递信息，使用字典
users = {}
class UserProcessor(threading.Thread):
    def __init__(self,c_sock):
        threading.Thread.__init__(self)
        self.sock = c_sock
        self.username = None
    def run(self):
        while True:
            data = self.sock.recv(1000)
            # 为空则移除数据
            if data is None or len(data) == 0:
                if self.username:
                    del users[self.username]
                    break
            try:
                # trip()去掉前后的多余空格和符号（linux -- \r\n）
                data = data.decode("utf-8").strip()
                data = json.load(data)
                if data["command"] == "register":
                    user = data["username"]
                    # self.username = user
                    users[user] = self.sock
                elif data["command"] == "message":
                    to = data["to"]
                    if to not in users:
                        self.sock.send("该用户不存在！")
                        continue
                    sock = users[to]
                    # 使用json.dumps将数据序列化
                    sock.send(json.dumps(data).encode("utf-8"))
                else:
                    self.sock.send("unkonwn")
                # print("data ---utf-8--{}".format(data))
                # if data == "exit":
                #     break
                # else:
                #     # 内部命令输出(linux中命令行为此处的data)
                #     os.system(data)
                #     self.sock.send("成功输出".encode("utf-8"))
            except Exception as e:
                # 打印详细异常信息
                traceback.print_exc()
        self.sock.close()
# 服务器
if len(sys.argv) < 2:
    print("usage:{}address port".format(sys.argv[0]))
    sys.exit(1)
# 默认全局地址
# address = "0.0.0.0"
# address = "127.0.0.1"
# port = 3000
address = sys.argv[1]
port = int(sys.argv[2])
#     返回soket 对象
s_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
# 绑定ip地址和端口(bind)
s_sock.bind((address,port))
# 监听
s_sock.listen(100)
while True:
    # 接受客户端连接（保存客户端的套接字对象）
    c_sock, remote = s_sock.accept()
    thread = UserProcessor(c_sock)
    # 保护主线程，在start()方法之前,此处不使用join线程原因在于使用造成主线程阻塞（暂时理解）
    thread.setDaemon(True)
    thread.start()
    # print("端口已经连接{}{}".format(c_sock,remote))
    # # 读写数据（send/recv）
    # data = c_sock.recv(1000)
    # print("DATA:{}".format(data))
    # c_sock.send(data)
    # # 关闭套接字对象
    # c_sock.close()
#     关闭服务器
s_sock.close()
